package com.heima.datastructure.deque;

import java.util.Iterator;

import static com.heima.datastructure.deque.ArrayDeque1.dec;
import static com.heima.datastructure.deque.ArrayDeque1.inc;

/**
 * 用循环数组实现双端队列方法二
 * @author 勾新杰
 * @version 1.0
 * @date 2024/9/2 18:01
 */
public class ArrayDeque2<E> implements Deque<E>, Iterable<E> {
    private E[] arr; // 数组
    private int head; // 头指针，指向头元素，默认初始化为0
    private int tail; // 尾指针，指向尾元素的下一个元素，默认初始化为0
    private int size; // 双端队列的大小，默认初始化为0

    /**
     * 用构造方法初始化
     * @param capacity 容量
     */
    @SuppressWarnings("all")
    public ArrayDeque2(int capacity) {
        arr = (E[]) new Object[capacity]; // 不用考虑head和tail
    }

    /**
     * 向双端队列左端加入元素
     * @param value 待入队的值
     * @return 入队成功返回true
     */
    @Override
    public boolean offerFirst(E value) {
        if (isFull()){
            return false;
        }
        head = dec(head, arr.length);
        arr[head] = value;
        size++;
        return true;
    }

    /**
     * 向双端队列右端加入元素
     * @param value 待入队的值
     * @return 入队成功返回true
     */
    @Override
    public boolean offerLast(E value) {
        if (isFull()){
            return false;
        }
        arr[tail] = value;
        tail = inc(tail,arr.length);
        size++;
        return true;
    }

    /**
     * 向双端队列左端获取元素并删除
     * @return 双端队列左端获取元素
     */
    @Override
    public E pollFirst() {
        if (isEmpty()){
            return null;
        }
        E value = arr[head];
        arr[head] = null;
        head = inc(head,arr.length);
        size--;
        return value;
    }

    /**
     * 向双端队列右端获取元素并删除
     * @return 双端队列右端获取元素
     */
    @Override
    public E pollLast() {
        if (isEmpty()){
            return null;
        }
        tail = dec(tail,arr.length);
        E value = arr[tail];
        arr[tail] = null;
        size--;
        return value;
    }

    /**
     * 向双端队列左端获取元素
     * @return 双端队列左端获取元素
     */
    @Override
    public E peekFirst() {
        if (isEmpty()){
            return null;
        }
        return arr[head];
    }

    /**
     * 向双端队列右端获取元素
     * @return 双端队列右端获取元素
     */
    @Override
    public E peekLast() {
        if (isEmpty()){
            return null;
        }
        return arr[dec(tail,arr.length)];
    }

    /**
     * 判断是否为空
     * @return 为空返回true
     */
    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 判断是否为满
     * @return 为满返回true
     */
    @Override
    public boolean isFull() {
        return size == arr.length;
    }

    /**
     * 获取双端队列大小
     * @return 大小
     */
    @Override
    public int size() {
        return size;
    }

    /**
     * 迭代器
     * @return 迭代器
     */
    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int index = head;
            int size = 0;
            @Override
            public boolean hasNext() {
                return size != size();
            }

            @Override
            public E next() {
                E value = arr[index];
                index = inc(index, arr.length);
                size++;
                return value;
            }
        };
    }

    /**
     * 扩容
     * @param capacity 容量
     * @throws IllegalArgumentException 传入的容量大小小于原始的容量大小
     */
    @SuppressWarnings("all")
    public void expansion(int capacity){
        if (capacity < arr.length){
            throw new IllegalArgumentException("参数"+capacity+"不能比"+ size +"小");
        }
        E[] array = (E[]) new Object[capacity];
        int index = 0;
        for (E value : this) {
            array[index++] = value;
        }
        head = 0;
        tail = index;
        arr = array; // arr指向的原来的数组对象没有变量指向它，会被垃圾回收机制回收
    }
}
